﻿using System;
using System.Collections.Generic;
using UnityEngine;
using Network;

public class VisualEntity:MonoBehaviour
{
    public uint entityID { private set; get; }
    protected Logic logic;
    List<VisualComponent> components = new List<VisualComponent>();
    public string PrefabPath;

    public static VisualEntity InitVisualEntitiy(string prefabPath, uint entityID)
    {
        GameObject go = (GameObject)Instantiate(Resources.Load(prefabPath));
        VisualEntity vEntity = go.GetComponent<VisualEntity>();
        vEntity.entityID = entityID;
        vEntity.PrefabPath = prefabPath;
        return vEntity;
    }

    public virtual void Destroy()
    {
        for (int i = 0; i < components.Count; i++)
        {
            components[i].OnDestroy(); 
        }
    }

    public void SetLogic(Logic logic)
    {
        this.logic = logic;
    }

    public T GetVisualComponent<T>() where T : class, VisualComponent
    {
        for (int i = 0; i < components.Count; i++)
        {
            if (components[i] is T)
                return (T)components[i];
        }

        return null;
    }

    public void AddVisualComponent(VisualComponent component)
    {
        components.Add(component);
        component.Init(this);
    }

    void Update()
    {
        if(logic != null)
        {
            logic.Update(Time.deltaTime);
        }

        for (int i = 0; i < components.Count; i++)
        {
            components[i].DoUpdate(Time.deltaTime);
        }
    }

    #region network

    private Dictionary<uint, Action<byte[]>> _msgDispatch = new Dictionary<uint, Action<byte[]>> ();

    public void RegistMsg(uint f_id, Action<byte[]> f_func)
    {
        if (_msgDispatch.ContainsKey(f_id))
            _msgDispatch[f_id] += f_func;
        else
            _msgDispatch.Add(f_id, f_func);
    }

    public void UnregistMsg(uint f_id)
    {
        if (_msgDispatch.ContainsKey(f_id))
        {
            _msgDispatch.Remove(f_id);
        }
        else
            Debug.LogWarning("Unregist unknow Message : " + f_id.ToString());
    }

    public void DispatchMsg(uint msgID, byte[] msg)
    {
        if (_msgDispatch.ContainsKey(msgID))
        {
            Action<byte[]> fn = _msgDispatch[msgID];
            fn(msg);
        }
        else
        {
            Debug.Log("Receive unknow Message : " + msgID.ToString());
        }
    }
    #endregion

    #region sync_state

    public void GetSyncMessage(sync_state_content message)
    {
        for(int i = 0; i < components.Count; i++)
        {
            components[i].GetSyncMessage(message);
        }
    }

    public void RestoreState(sync_state_content message)
    {
        for(int i = 0; i < components.Count; i++)
        {
            components[i].RestoreState(message);
        }
    }

    #endregion
}
